#include <linux/init.h>
#include <linux/module.h>

#include <linux/device.h>

/************************************************************************
	* 函数负责实现总线下的设备和驱动匹配的机制
	* 使用字符串比较的方式，通过对比驱动以及设备的名字来确定是否匹配，
	* 如果相同， 则说明匹配成功，返回1；反之，则返回0
	***********************************************************************/
int mybus_match(struct device *dev, struct device_driver *drv)
{
	printk("%s-%s\n", __FILE__, __func__);
	if (!strncmp(dev_name(dev), drv->name, strlen(drv->name))) {
		printk("dev & drv match\n");
		return 1;
	}
	return 0;

}

//定义了一个bus_name变量，存放了该总线的名字
static char *bus_name = "mybus";
//提供show回调函数，这样用户便可以通过cat命令， 来查询总线的名称
ssize_t mybus_test_show(struct bus_type *bus, char *buf)
{
	return sprintf(buf, "%s\n", bus_name);
}
//设置该文件的文件权限为文件拥有者可读，组内成员以及其他成员不可操作
BUS_ATTR(mybus_test, S_IRUSR, mybus_test_show, NULL);

//定义了一种新的总线，名为mybus，总线结构体中最重要的一个成员，便是match回调函数
static struct bus_type mybus = {
	.name = "mybus",
	.match = mybus_match,
};

EXPORT_SYMBOL(mybus);

//注册总线
static __init int mybus_init(void)
{
	int ret;
	printk("mybus init\n");

	ret = bus_register(&mybus);
	if(ret)
		printk("mybus register failed\n");

	ret = bus_create_file(&mybus, &bus_attr_mybus_test);
	return 0;
}

module_init(mybus_init);

//注销总线
static __exit void mybus_exit(void)
{
	printk("mybus exit\n");
	bus_remove_file(&mybus, &bus_attr_mybus_test);
	bus_unregister(&mybus);
}

module_exit(mybus_exit);

MODULE_AUTHOR("wff");
MODULE_LICENSE("GPL");
